/**
 * 
 */
package adnotatio.renderer.templates;

import java.util.HashMap;
import java.util.Map;

import adnotatio.renderer.templates.FieldPanel.InternalHTMLPanel;

import com.google.gwt.xml.client.Element;

class FieldPanelGenerator {

    private class Slot {

        private StringBuffer fBuf;

        private FieldInfo fField;

        private String fId;

        private Map fMap;

        private FieldPanelGenerator.Slot fParent;

        public Slot(FieldPanelGenerator.Slot parent, FieldInfo field) {
            fId = "__tmps_" + fIdCounter++;
            fParent = parent;
            fField = field;
            if (fParent == null || fField instanceof IContainerField) {
                fBuf = new StringBuffer();
                fMap = new HashMap();
            }
            if (fParent != null) {
                fParent.addChild(this);
            }
        }

        private void addChild(Slot slot) {
            if (fMap != null) {
                fMap.put(slot.fId, slot.fField);
                fBuf.append("<span id='" + slot.fId + "'></span>");
            }
            if (fField != null) {
                fField.addChildFieldInfo(slot.fField);
            }
        }

        public void addText(String str) {
            if (fBuf != null)
                fBuf.append(str);
        }

        public void done() {
            InternalHTMLPanel panel = fParent == null
                ? fPanel.getPanel()
                : fField instanceof IContainerField
                    ? fPanel.newTemplatePanel()
                    : null;
            if (panel != null) {
                panel.setPanelContent(fBuf.toString(), fMap);
                if (fField instanceof IContainerField) {
                    ((IContainerField) fField).setContentWidget(panel);
                }
            }
        }

        public FieldPanelGenerator.Slot getParent() {
            return fParent;
        }

    }

    private static int fIdCounter;

    private FieldPanel fPanel;

    private Slot fSlot;

    public FieldPanelGenerator(FieldPanel panel) {
        fPanel = panel;
    }

    public void addText(String str) {
        fSlot.addText(str);
    }

    public void beginField(IFieldInfoFactory fieldFactory, Element e) {
        FieldInfo field = fieldFactory != null ? fieldFactory.newFieldInfo(
            fPanel,
            e) : null;
        fSlot = new Slot(fSlot, field);
    }

    public void endField() {
        fSlot.done();
        fSlot = fSlot.getParent();
    }

}